package com.derbysoft.synxisadapter.dswitch3.service.impl;

import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailRequest;
import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailResponse;
import com.derbysoft.dswitch.remote.hotel.dto.HotelReservationRequest;
import com.derbysoft.dswitch.remote.hotel.dto.HotelReservationResponse;
import com.derbysoft.synxisadapter.commons.model.Reservation;
import com.derbysoft.synxisadapter.commons.repository.ReservationRepository;
import com.derbysoft.synxisadapter.commons.utils.ErrorMessageUtils;
import com.derbysoft.synxisadapter.dswitch2.translator.Translator;
import com.derbysoft.synxisadapter.dswitch3.service.HotelProviderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * User: jason
 * Date: 2012-11-21
 */
@Component("ds3PreviewService")
public class PreviewServiceImpl extends DS3AbstractService
        implements HotelProviderService<HotelReservationRequest, HotelReservationResponse> {

    private static Logger logger = LoggerFactory.getLogger(PreviewServiceImpl.class);

    @Autowired
    @Qualifier("ds3AvailabilityService")
    private HotelProviderService<HotelAvailRequest, HotelAvailResponse> ds3AvailabilityService;

    @Autowired
    @Qualifier("ds3HotelPreviewRQTranslator")
    private Translator<HotelReservationRequest, HotelAvailRequest, Void> ds3HotelPreviewRQTranslator;

    @Autowired
    @Qualifier("ds3HotelPreviewRSTranslator")
    private Translator<HotelAvailResponse, HotelReservationResponse, HotelReservationRequest> ds3HotelPreviewRSTranslator;

    @Autowired
    private ReservationRepository reservationRepository;

    @Override
    public HotelReservationResponse execute(HotelReservationRequest request) {
        try {

            HotelAvailRequest hotelAvailRequest = ds3HotelPreviewRQTranslator.translate(request, null);

            HotelAvailResponse hotelAvailResponse = ds3AvailabilityService.execute(hotelAvailRequest);

            HotelReservationResponse response = ds3HotelPreviewRSTranslator.translate(hotelAvailResponse, request);
            if (response.getError() != null) {
                updateStatus(request.getHotelReservationRQ().getErsp(), Reservation.Status.PREVIEW_FAILED);
            }
            return response;
        } catch (Exception ex) {
            updateStatus(request.getHotelReservationRQ().getErsp(), Reservation.Status.PREVIEW_FAILED);
            logger.error(ErrorMessageUtils.buildErrorMessage(ex));
            return createErrorResponse(request, ex);
        }
    }

    private void updateStatus(String ersp, Reservation.Status status) {
        reservationRepository.updateStatus(ersp, status);
    }

    private HotelReservationResponse createErrorResponse(HotelReservationRequest request, Exception ex) {
        HotelReservationResponse response = new HotelReservationResponse();
        response.setTaskId(request.getHeader().getTaskId());
        response.setError(createDS3ErrorDTO(ex));
        return response;
    }
}
